﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Collections.ObjectModel;

namespace DotConsulting.VisualStudio.BuildOutputCopy.Model
{
    public class ProjectBuildInfo
    {

        private EnvDTE.Project _dteProject;

        public SolutionBuildInfo Parent { get; private set; }
        public string Platform { get; private set; }
        public DirectoryInfo OutputDir { get; private set; }
        public ObservableCollection<OutputFileInfo> OutputFiles { get; private set; }
        public bool Buildable { get; private set; }


        public ProjectBuildInfo(EnvDTE.Project dteProject, SolutionBuildInfo parent)
        {
            _dteProject = dteProject;
            Parent = parent;
            Refresh();
        }

        public string Name
        {
            get
            {
                return _dteProject.Name;
            }
        }

        private void Refresh()
        {
            Platform = _dteProject.ConfigurationManager.ActiveConfiguration.PlatformName;
            var projectDir = Path.GetDirectoryName(_dteProject.FullName);
            var outputProperty = (string)_dteProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value;
            OutputDir = new DirectoryInfo(Path.Combine(projectDir, outputProperty));
            Buildable = _dteProject.ConfigurationManager.ActiveConfiguration.IsBuildable;

            var assName = (string)_dteProject.Properties.Item("AssemblyName").Value;
            var searchPattern = string.Concat(assName, ".*");

            var allFiles = OutputDir.GetFiles(searchPattern, SearchOption.TopDirectoryOnly);

            OutputFiles = new ObservableCollection<OutputFileInfo>( (
                from f in allFiles
                where f.Name.Contains(".vshost.") == false
                select new OutputFileInfo(f, this)).ToList());

            // Add any file marked as 'CopyToOutput'

            var extraFiles = new List<FileInfo>();

            foreach (EnvDTE.ProjectItem pi in _dteProject.ProjectItems)
            {
                GetExtraFiles(pi, ref extraFiles);
            }

            extraFiles.ForEach( s => OutputFiles.Add(new OutputFileInfo(s, this)));

        }

        private void GetExtraFiles(EnvDTE.ProjectItem pi, ref List<FileInfo> extraFiles)
        {
            if (pi.Kind == EnvDTE.Constants.vsProjectItemKindVirtualFolder 
                || pi.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFolder)
            {
                foreach (EnvDTE.ProjectItem subpi in pi.ProjectItems)
                {
                    GetExtraFiles(subpi, ref extraFiles);
                }
            }
            else
            {
                if (pi.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFile)
                {
                    var copyToOutput = (pi.Properties.Item("CopyToOutputDirectory").Value.ToString() != "0");

                    if (copyToOutput && pi.Name.ToLowerInvariant() != "app.config")
                    {
                        var extraFile = new FileInfo(Path.Combine(OutputDir.FullName, pi.Name));
                        if (extraFile.Exists)
                        {
                            extraFiles.Add(extraFile);
                        }
                    }

                }
            }
        }
    }
}
